﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
using System.Linq;


namespace TetrisAlgorithm
{
    /// <summary>
    /// 移动方向枚举
    /// </summary>
    public enum MoveEnum
    {
        向左 = 0,
        向右 = 1,
        向下 = 2,
        向上 = 3
    }
    public class FigureMove
    {

        List<FigureInfo> _listAccumulateInfo = new List<FigureInfo>();
        /// <summary>
        /// 堆积的方块，未消的方块
        /// </summary>
        public List<FigureInfo> listAccumulateInfo
        {
            get { return _listAccumulateInfo; }
            set{_listAccumulateInfo=value;}
        }
        /// <summary>
        /// 间隔
        /// </summary>
        int infoS = 21;
        /// <summary>
        /// 每行方块数
        /// </summary>
        int infoCount = 10;
        List<FigureInfo> _listInfo;
        /// <summary>
        /// 集合
        /// </summary>
        public List<FigureInfo> listInfo
        {
            get { return _listInfo; }
            set { _listInfo = value; }
        }

        FigureInfo _figureInfo;
        /// <summary>
        /// 要移动的对象
        /// </summary>
        public FigureInfo figureInfo
        {
            get { return _figureInfo; }
            set { _figureInfo = value; }
        }
        Point _maxPoint = new Point(0, 0);
        /// <summary>
        /// 最大坐标
        /// </summary>
        public Point maxPoint
        {
            get { return _maxPoint; }
            set { _maxPoint = value; }
        }
        /// <summary>
        /// 集合移动 向下
        /// </summary>
        /// <returns></returns>
        public List<Point> MoveDown()
        {
            List<Point> listPo = new List<Point>();
            bool isMove = true;
            foreach (FigureInfo item in _listInfo)
            {
                listPo.Add(MoveDown(item,out isMove));
                if (!isMove)
                {
                    break;
                }               
            }
            if (!isMove)
            {
                return null;
            }
            else
            {
                return listPo;
            }
        }
        /// <summary>
        /// 集合移动 向下
        /// </summary>
        /// <returns></returns>
        public List<Point> MoveLeft()
        {
            List<Point> listPo = new List<Point>();
            bool isMove = true;
            foreach (FigureInfo item in _listInfo)
            {
                listPo.Add(MoveLeft(item, out isMove));
                if (!isMove)
                {
                    break;
                }
            }
            if (!isMove)
            {
                return null;
            }
            else
            {
                return listPo;
            }
        }

        /// <summary>
        /// 集合移动 向下
        /// </summary>
        /// <returns></returns>
        public List<Point> MoveRight()
        {
            List<Point> listPo = new List<Point>();
            bool isMove = true;
            foreach (FigureInfo item in _listInfo)
            {
                listPo.Add(MoveRight(item, out isMove));
                if (!isMove)
                {
                    break;
                }
            }
            if (!isMove)
            {
                return null;
            }
            else
            {
                return listPo;
            }
        }
        /// <summary>
        /// 向下移动
        /// </summary>
        private Point MoveDown(FigureInfo sinfo,out bool isMove)
        {
            Point po = sinfo.figurePoint;
            if (!isCanMove(sinfo, MoveEnum.向下))
            {
                isMove = false;
                return new Point(po.X, po.Y);
            }
            //先判断是否超过最大坐标
            if (po.Y >= _maxPoint.Y - infoS) //|| po.Y >= _maxPoint.Y - infoS)
            {
                isMove = false;
                return new Point(po.X, po.Y);
            }
            else//向下移动
            {
              //  sinfo.figurePoint = new Point(po.X, po.Y + infoS);
                isMove = true;
                return new Point(po.X, po.Y + infoS);
            }

        }
        /// <summary>
        /// 向左移动
        /// </summary>
        private Point MoveLeft(FigureInfo sinfo, out bool isMove)
        {
            Point po = sinfo.figurePoint;
            if (!isCanMove(sinfo, MoveEnum.向左))
            {
                isMove = false;
                return new Point(po.X, po.Y);
            }
             if (po.X <= 0 )//|| po.Y <= 0)//判断是否出边界
            {
                isMove = false;
                return new Point(po.X, po.Y);
            }
            else//向左移动
            {
               // sinfo.figurePoint = new Point(po.X - infoS, po.Y);
                isMove = true;
                return new Point(po.X - infoS, po.Y);
            }
        }
        /// <summary>
        /// 向右移动
        /// </summary>
        private Point MoveRight(FigureInfo sinfo, out bool isMove)
        {
            Point po = sinfo.figurePoint;
            if (!isCanMove(sinfo, MoveEnum.向右))
            {
                isMove = false;
                return new Point(po.X, po.Y);
            }
            //先判断是否超过最大坐标
            if (po.X >= _maxPoint.X - infoS )//|| po.Y >= _maxPoint.Y - infoS)
            {
                isMove = false;
                return new Point(po.X, po.Y);
            }
            else//向右移动
            {
             //   sinfo.figurePoint = new Point(po.X + infoS, po.Y);
                isMove = true;
                return new Point(po.X + infoS, po.Y);
            }
        }
        /// <summary>
        /// 是否可以移动
        /// </summary>
        /// <param name="sinfo"></param>
        /// <returns></returns>
        private bool isCanMove(FigureInfo sinfo,MoveEnum mEnum)
        {
            bool _isCanMove = true;
            Point po = sinfo.figurePoint;
            List<FigureInfo> listM;
            if (_listAccumulateInfo == null)
                return true;
            if (mEnum == MoveEnum.向下)
            {
                listM=(from t in _listAccumulateInfo where t.figurePoint.X==po.X select t).ToList();
                if (listM != null)
                {
                    foreach (FigureInfo item in listM)
                    {
                        if (po.Y + infoS >= item.figurePoint.Y)
                        {
                            return false;
                        }
                    }
                }
            }
            else if (mEnum == MoveEnum.向左)
            {
                listM = (from t in _listAccumulateInfo where t.figurePoint.Y == po.Y select t).ToList();
                if (listM != null)
                {
                    foreach (FigureInfo item in listM)
                    {
                        if (po.X + infoS >= item.figurePoint.X)
                        {
                            return false;
                        }
                    }
                }
            }
            else if (mEnum == MoveEnum.向右)
            {
                listM = (from t in _listAccumulateInfo where t.figurePoint.Y == po.Y select t).ToList();
                if (listM != null)
                {
                    foreach (FigureInfo item in listM)
                    {
                        if (po.X + infoS <= item.figurePoint.X)
                        {
                            return false;
                        }
                    }
                }
            }
            return _isCanMove;
        }
        /// <summary>
        /// 是否可以删除
        /// </summary>
        /// <returns></returns>
        public bool isCanRemove()
        {
            if (_listAccumulateInfo == null)
                return true;
            List<int> listInt = (from t in _listAccumulateInfo select t.figurePoint.Y).Distinct().ToList();
            if (listInt != null)
            {
                foreach (int item in listInt)
                {
                    List<FigureInfo> listRem = (from a in _listAccumulateInfo where a.figurePoint.Y == item select a).ToList();
                    if (listRem.Count >= infoCount)
                    { 
                        //删除逻辑
                    }
                }
            }
            return true;
        }
    }
    /// <summary>
    /// 图形对象
    /// </summary>
    public class FigureInfo:Panel
    {
        /// <summary>
        /// 移动对象
        /// </summary>
        public object obFigure;
        Point _figurePoint = new Point(0, 0);
        /// <summary>
        /// 坐标
        /// </summary>
        public Point figurePoint
        {
            get
            {
                return _figurePoint;
            }
            set
            {
                _figurePoint = value;
            }
        }

        Size _figureSize = new Size(10, 10);
        /// <summary>
        /// 大小
        /// </summary>
        public Size figureSize
        {
            get 
            {
                return _figureSize;
            }
            set 
            {
                _figureSize = value;
            }
        }
        
    }
    /// <summary>
    /// 组装
    /// </summary>
    public class AssemblingFigureInfo:FigureInfo
    {
 
      
        public List<FigureInfo> getInfos(List<Point> listPo)
        {
            List<FigureInfo> listInfo = new List<FigureInfo>();
            for (int i = 0; i < 4; i++)
            {
                FigureInfo infoOne = new FigureInfo();
                infoOne.Size = new System.Drawing.Size(20, 20);
                infoOne.BackColor = Color.White;
                infoOne.figurePoint = listPo[i];
                listInfo.Add(infoOne);
            }
            return listInfo;
        }
        #region 正方形
        //正方形
        /// <summary>
        /// 得到正方形坐标
        /// </summary>
        /// <returns></returns>
        public List<Point> GetSqurePoint()
        {
            List<Point> listPo = new List<Point>();
            listPo.Add(new Point(0, 0));
            listPo.Add(new Point(21, 0));
            listPo.Add(new Point(0, 21));
            listPo.Add(new Point(21, 21));
            return listPo;
        }
        /// <summary>
        /// 得到四个小方块
        /// </summary>
        /// <returns></returns>
        public List<FigureInfo> GetSqureInfo()
        {
            
            List<Point> listPo = GetSqurePoint();
            List<FigureInfo> listInfo = getInfos(listPo);            
            return listInfo;
        }
        #endregion
        #region 长方形
        /// <summary>
        /// 长方形
        /// </summary>
        /// <returns></returns>
        public List<Point> GetRectanglePoint()
        {
            List<Point> listPo = new List<Point>();
            listPo.Add(new Point(0, 0));
            listPo.Add(new Point(21, 0));
            listPo.Add(new Point(42, 0));
            listPo.Add(new Point(63, 0));
            return listPo;
        }
        /// <summary>
        /// 长方形
        /// </summary>
        /// <returns></returns>
        public List<FigureInfo> GetRectangleInfo()
        {
            List<Point> listPo = GetRectanglePoint();
            List<FigureInfo> listInfo = getInfos(listPo);
            return listInfo;
        }
        #endregion

        #region 组合1
        /// <summary>
        /// 组合1
        ///
        /// </summary>
        /// <returns></returns>
        public List<Point> GetAssemblingOnePoint()
        {
            List<Point> listPo = new List<Point>();
            listPo.Add(new Point(21, 0));
            listPo.Add(new Point(0, 21));
            listPo.Add(new Point(21, 21));
            listPo.Add(new Point(0, 42));
            return listPo;
        }
        /// <summary>
        /// 组合1
        /// </summary>
        /// <returns></returns>
        public List<FigureInfo> GetAssemblingOneInfo()
        {
            List<Point> listPo = GetAssemblingOnePoint();
            List<FigureInfo> listInfo = getInfos(listPo);
            return listInfo;
        }
        #endregion
        #region 组合2
        /// <summary>
        /// 组合2
        /// </summary>
        /// <returns></returns>
        public List<Point> GetAssemblingTwoPoint()
        {
            List<Point> listPo = new List<Point>();
            listPo.Add(new Point(0, 0));
            listPo.Add(new Point(21, 0));
            listPo.Add(new Point(42, 0));
            listPo.Add(new Point(21, 21));
            return listPo;
        }
        /// <summary>
        /// 组合2
        /// </summary>
        /// <returns></returns>
        public List<FigureInfo> GetAssemblingTwoInfo()
        {
            List<Point> listPo = GetAssemblingTwoPoint();
            List<FigureInfo> listInfo = getInfos(listPo);
            return listInfo;
        }

        #endregion
        #region 组合3
        /// <summary>
        /// 组合3
        /// </summary>
        /// <returns></returns>
        public List<Point> GetAssemblingThreaPoint()
        {
            List<Point> listPo = new List<Point>();
            listPo.Add(new Point(0, 0));
            listPo.Add(new Point(21, 0));
            listPo.Add(new Point(0, 21));
            listPo.Add(new Point(0, 42));
            return listPo;
        }
        /// <summary>
        /// 组合3
        /// </summary>
        /// <returns></returns>
        public List<FigureInfo> GetAssemblingThreaInfo()
        {
            List<Point> listPo = GetAssemblingThreaPoint();
            List<FigureInfo> listInfo = getInfos(listPo);
            return listInfo;
        }

       
        #endregion

    }
}
